/*
 *   Copyright (c) 2010-2022, SIUFUNG
 */
package net.siufung.market.base.dict.controller;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.siufung.core.model.enums.DeletedEnum;
import net.siufung.core.page.PagerResult;
import net.siufung.core.result.Result;
import net.siufung.core.result.ResultFail;
import net.siufung.core.result.ResultOk;
import net.siufung.core.utils.CopyUtil;
import net.siufung.market.base.dict.controller.assembler.DictTypeAssembler;
import net.siufung.market.base.dict.controller.model.dicttype.DictTypeDto;
import net.siufung.market.base.dict.controller.model.dicttype.DictTypePageDto;
import net.siufung.market.base.dict.controller.model.dicttype.DictTypeSaveDto;
import net.siufung.market.base.dict.controller.model.dicttype.DictTypeUpdateDto;
import net.siufung.market.base.dict.controller.model.dicttype.DictTypeVo;
import net.siufung.market.base.dict.controller.regulation.DictTypeRegulation;
import net.siufung.market.base.dict.mapper.IDictMapper;
import net.siufung.market.base.dict.mapper.IDictTypeMapper;
import net.siufung.market.base.dict.mapper.entity.Dict;
import net.siufung.market.base.dict.mapper.entity.DictType;
import net.siufung.market.base.dict.service.IDictTypeService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 字典类型 前端控制器
 *
 * @author 陈建峰
 * @since 2022-07-08 15:30:16
 */
@Api(tags = "字典类型")
@Slf4j
@AllArgsConstructor
@RestController
@RequestMapping("/data/dict/type")
public class DictTypeController {

    private final IDictTypeMapper dictTypeMapper;
    private final IDictTypeService dictTypeService;
    private final IDictMapper dictMapper;

    /**
     * 通过主键获取 字典类型
     * @param id 主键
     * @return Result<DictTypeVo>
     * */
    @ApiOperation(value = "通过Id获取字典类型信息")
    @GetMapping(value = "/id/{id}")
    public Result<DictTypeVo> getById(
            @PathVariable("id") Integer id) {
        return Result.ok(
            DictTypeAssembler.from(dictTypeMapper.selectById(id)));
    }

    /**
     * 获取 字典类型列表
     * @param dictTypeDto 属性
     * @return Result<List<DictTypeVo>>
     * */
    @ApiOperation(value = "获取字典类型列表")
    @PostMapping(value = "/list")
    public Result<List<DictTypeVo>> list(
            @RequestBody DictTypeDto dictTypeDto) {
        return Result.ok(
            DictTypeAssembler.fromList(dictTypeMapper.selectList(Wrappers.query(dictTypeDto.to()))));
    }

    /**
     * 获取 字典类型列表
     * @param dictTypeDto 属性
     * @return Result<List<DictTypeVo>>
     * */
    @ApiOperation(value = "获取字典类型列表")
    @PostMapping(value = "/listWidthDictList")
    public Result<List<DictTypeVo>> listWidthDictList(
            @RequestBody DictTypeDto dictTypeDto) {
        List<DictType> dictTypeList = dictTypeMapper.selectList(Wrappers.query(dictTypeDto.to()));
        List<Integer> dictTypeIdList = dictTypeList.stream()
                .map(DictType::getId).distinct().collect(Collectors.toList());
        List<Dict> dictList = Lists.newArrayList();
        if(CollectionUtil.isNotEmpty(dictTypeIdList)){
            dictList = dictMapper.selectList(
                    new LambdaQueryWrapper<Dict>().in(Dict::getDictTypeId, dictTypeIdList));
        }
        return Result.ok(
                DictTypeAssembler.fromList(dictTypeList, dictList));
    }

    /**
     * 获取 字典类型分页
     * @param dictTypePageDto 属性
     * @return 查询分页结果
     * */
    @ApiOperation(value = "获取字典类型分页")
    @PostMapping(value="/page")
    public Result<PagerResult<DictTypeVo>> getPage(
            @RequestBody DictTypePageDto dictTypePageDto) {
        dictTypePageDto.validated();
        QueryWrapper<DictType> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(!Strings.isNullOrEmpty(dictTypePageDto.getTypeCode()),
                DictType::getTypeCode, dictTypePageDto.getTypeCode());
        wrapper.lambda().eq(!Strings.isNullOrEmpty(dictTypePageDto.getTypeName()),
                DictType::getTypeName, dictTypePageDto.getTypeName());
        wrapper.lambda().orderByDesc(DictType::getId);
        IPage<DictType> dictTypePage = dictTypeMapper.selectPage(
                new Page<>(dictTypePageDto.getPageNo(), dictTypePageDto.getPageSize()), wrapper);
        PagerResult<DictTypeVo> dictTypeVoPage = new PagerResult<>(
                dictTypePage.getCurrent(), dictTypePage.getSize(), dictTypePage.getTotal());
        dictTypeVoPage.setRecords(
            DictTypeAssembler.fromList(dictTypePage.getRecords()));
        return Result.ok(dictTypeVoPage);
    }

    /**
     * 通过主键删除 字典类型 对象
     * @param id 主键
     * @return 删除结果
     * */
    @ApiOperation(value = "删除字典类型对象")
    @PostMapping(value="/delete/{id}")
    public Result<Void> deleteById(
        @PathVariable("id") Integer id) {
        DictTypeRegulation.Remove dictTypeDeleteRegulation = new DictTypeRegulation.Remove(dictTypeMapper, dictMapper);
        dictTypeDeleteRegulation.isSatisfiedBy(id);
        if(dictTypeService.removeById(id)){
            return Result.ok(ResultOk.REMOVE);
        }
        return Result.fail(ResultFail.DATA_REMOVE_ERROR);
    }

    /**
     * 创建 字典类型
     * @param dictTypeSaveDto 对象属性
     * @return 创建结果
     * */
    @ApiOperation(value = "创建 字典类型")
    @PostMapping(value="/create")
    public Result<Void> create(
            @RequestBody DictTypeSaveDto dictTypeSaveDto) {
        dictTypeSaveDto.validated();
        DictTypeRegulation.Save dictTypeCreateRegulation = new DictTypeRegulation.Save(dictTypeMapper);
        dictTypeCreateRegulation.isSatisfiedBy(dictTypeSaveDto);
        if(dictTypeService.save(dictTypeSaveDto.to())){
            return Result.ok(ResultOk.ADD);
        }
        return Result.fail(ResultFail.DATA_ADD_ERROR);
    }

    /**
     * 更新 字典类型
     * @param dictTypeUpdateDto 对象属性
     * @return Result<Void>
     * */
    @ApiOperation(value = "更新 字典类型 信息")
    @PostMapping(value="/updateById")
    public Result<Void> updateById(
            @RequestBody DictTypeUpdateDto dictTypeUpdateDto) {
        dictTypeUpdateDto.validated();
        DictTypeRegulation.Update dictTypeCreateRegulation = new DictTypeRegulation.Update(dictTypeMapper);
        dictTypeCreateRegulation.isSatisfiedBy(dictTypeUpdateDto);
        DictType dictTypeOf = dictTypeService.getById(dictTypeUpdateDto.getId());
        CopyUtil.copyPropertiesIgnoreNull(dictTypeUpdateDto.to(), dictTypeOf);
        if(dictTypeService.updateById(dictTypeOf)){
            return Result.ok(ResultOk.UPDATE);
        }
        return Result.fail(ResultFail.DATA_UPDATE_ERROR);
    }

    /**
     * 更新 字典类型 状态
     * @param id 主键
     * @param deleted 数据状态
     * @return Result<Void>
     * */
    @ApiOperation(value = "更新 字典类型 状态")
    @PostMapping(value="/status/{id}/{deleted}")
    public Result<Void> updateStatusById(
            @PathVariable("id") Integer id,
            @PathVariable("deleted") boolean deleted) {
        DictTypeRegulation.Status dictTypeStatusRegulation = new DictTypeRegulation.Status(dictTypeMapper);
        dictTypeStatusRegulation.isSatisfiedBy(id);
        if(dictTypeService.updateStatusById(id, DeletedEnum.get(deleted))){
            return Result.ok(ResultOk.STATUS);
        }
        return Result.fail(ResultFail.DATA_UPDATE_ERROR);
    }

}